#include <iostream>
#include <vector>
#include <string>
#include <sw/redis++/redis++.h>
#include "until.hpp"
#include <thread>
using namespace std;
using namespace chrono_literals;

void test1(sw::redis::Redis& redis)
{
    cout << "test set get 一部分" << endl;
    redis.flushall();
    redis.set("key1","111");
    redis.set("key2","222");
    redis.set("key3","333");

    auto ret = redis.get("key1");
    if(ret)
        cout << ret.value() << endl;

    ret = redis.get("key2");
    if(ret)
        cout << ret.value() << endl;

    ret = redis.get("key3");
    if(ret)
        cout << ret.value() << endl;

    ret = redis.get("key4");
    if(ret)
        cout << ret.value() << endl;
}

void test2(sw::redis::Redis& redis)
{
    cout << "test del" << endl;

    redis.flushall();

    redis.set("key1","111");
    redis.set("key2","222");
    redis.set("key3","333");

    auto ret = redis.del("key1");
    cout << ret << endl;

    auto str = redis.get("key1");
    if(str)
        cout << str.value() << endl;
    else
        cout << "del done" << endl;
}

void test3(sw::redis::Redis& redis)
{
    cout << "test keys" << endl;

    redis.flushall();
    redis.set("key1","111");
    redis.set("key2","222");
    redis.set("key3","333");
    redis.set("key4","444");
    redis.set("key5","555");


    std::vector<string> vs;
    std::back_insert_iterator<std::vector<string>> bit(vs);

    redis.keys("*",bit);
    PrintElenums(vs);
}

void test4(sw::redis::Redis& redis)
{
    cout << "test expire kttl" << endl;

    using namespace chrono_literals;

    redis.flushall();
    redis.set("key1","111");

    redis.expire("key1",10s);
    std::this_thread::sleep_for(3s);

    auto ret = redis.ttl("key1");
    cout << ret << endl;
}

void test5(sw::redis::Redis& redis)
{
    cout << "test type" << endl;

    redis.flushall();

    redis.set("key1","111");
    string str1 = redis.type("key1");
    cout << "key1: " << str1 << endl;

    redis.lpush("key2","222");
    str1 = redis.type("key2");
    cout << "key2: " << str1 << endl;

    redis.hset("key3","aaa","333");
    str1 = redis.type("key3");
    cout << "key3: " << str1 << endl;

    redis.sadd("key4","444");
    str1 = redis.type("key4");
    cout << "key4: " << str1 << endl;

    redis.zadd("key5","关羽",95);
    str1 = redis.type("key5");
    cout << "key5: " << str1 << endl;
}

void test6(sw::redis::Redis& redis)
{
    cout << "test set nx xx" << endl;
    redis.flushall();

    //nx 不存在则创建
    redis.set("key1","111",0s,sw::redis::UpdateType::NOT_EXIST);

    auto val = redis.get("key1");
    if(val)
        cout << val.value() << endl;

    //xx 存在则更新
    redis.set("key1","222",0s,sw::redis::UpdateType::EXIST);

    val = redis.get("key1");
    if(val)
        cout << val.value() << endl;
}

void test7(sw::redis::Redis& redis)
{
    cout << "test mset mget" << endl;
    redis.flushall();

    //redis.mset({std::make_pair("key1","111"),std::make_pair("key2","222"),std::make_pair("key3","333")});
    

    vector<pair<string,string>> vpss;

    vpss.push_back(make_pair("key1","111"));
    vpss.push_back(make_pair("key2","222"));
    vpss.push_back(make_pair("key3","333"));

    //插入键值对
    redis.mset(vpss.begin(),vpss.end());

    
    vector<string> keytmp;

    //提取key到keytmp里
    for(auto& e : vpss)
        keytmp.push_back(e.first);

    vector<sw::redis::OptionalString> vos;
    std::back_insert_iterator<vector<sw::redis::OptionalString>> bit(vos);

    //把读到key对应的value存到vos里
    redis.mget(keytmp.begin(),keytmp.end(),bit);
    PrintElenums(vos);

}

void test8(sw::redis::Redis& redis)
{
    cout << "test getrange setrange" << endl;
    redis.flushall();

    redis.set("key1","abcdefg");

    string ret = redis.getrange("key1",2,5);
    cout << ret << endl;

    redis.setrange("key1",2,"zzz");

    auto r = redis.get("key1");
    cout << r.value() << endl;
}

void test9(sw::redis::Redis& redis)
{
    cout << "test getrange setrange" << endl;
    redis.flushall();

    redis.set("key1","100");

    auto ret1 = redis.incr("key1");
    cout << "val incr done :" << ret1 << endl;

    auto ret2 = redis.decr("key1");
    cout << "val decr done :" << ret2 << endl;
}

int main()
{
    sw::redis::Redis redistmp("tcp://127.0.0.1:6379");
    //test1(redistmp);
    //test2(redistmp);
    //test3(redistmp);
    //test4(redistmp);
    //test5(redistmp);
    //test6(redistmp);
    //test7(redistmp);
    // test8(redistmp);
    test9(redistmp);
    return 0;
}